<?php

namespace App\Admin\Controllers;

use App\Admin\Repositories\UserCoin;
use App\Models\Coin;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Show;
use Dcat\Admin\Http\Controllers\AdminController;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;

class UserCoinController extends AdminController
{
    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        return Grid::make(new UserCoin(), function (Grid $grid) {
            $grid->model()
                ->leftJoin('coin', 'coin.id', '=', 'user_coin.coin_id')
                ->leftJoin('users', 'users.id', '=', 'user_coin.user_id')
                ->where('coin.is_true', Coin::IS_TRUE_YES)
                ->where('user_coin.parent_coin_id', 0)
                ->selectRaw('user_coin.id,user_coin.pay_status,user_coin.created_at,user_coin.pay_time,user_coin.apply_status,user_coin.apply_time,user_coin.content,coin.name,coin.cost,coin.type,users.name as user_name,users.mobile')
                ->orderByRaw('user_coin.id desc');
            $grid->column('id');
            $grid->column('user_name', '用户名');
            $grid->column('mobile', '手机号');
            $grid->column('name', '硬币名称');
            $grid->column('type', '硬币类型')->display(function ($type) {
                return \App\Models\Coin::TYPE[$type];
            });
            $grid->column('cost', '价值(元)');
            $grid->column('content', '视频')->display(function ($content) {
                return $content ? '<a href="' . $content . '" target="_blank">查看</a>' : '-';
            });
            $grid->column('apply_status', '申请状态')->display(function ($apply_status) {
                return \App\Models\UserCoin::APPLY_STATUS[$apply_status];
            });
            $grid->column('apply_time', '申请时间');
            $grid->column('pay_status', '兑付状态')->select(\App\Models\UserCoin::PAY_STATUS, true);
            $grid->column('pay_time', '兑付时间');
            $grid->column('created_at', '获取时间');

            $grid->filter(function (Grid\Filter $filter) {
                $filter->equal('mobile', '手机号');
            });

            $grid->disableActions();
            $grid->disableCreateButton();
            $grid->disableBatchActions();
            $grid->disableRowSelector();
        });
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     *
     * @return Show
     */
    protected function detail($id)
    {
        return Show::make($id, new UserCoin(), function (Show $show) {
            $show->field('id');
            $show->field('user_id');
            $show->field('coin_id');
            $show->field('content');
            $show->field('created_at');
            $show->field('updated_at');
        });
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        return Form::make(new UserCoin(), function (Form $form) {
            $form->display('id');
            $form->text('pay_status');
            $form->text('pay_time');
            $form->saving(function (Form $form) {
                // 获取用户信息和金额
                $userCoin = \App\Models\UserCoin::with(['user', 'coin'])->find($form->model()->id);

                $form->pay_time = '';
                if ($form->pay_status == \App\Models\UserCoin::PAY_STATUS_YES) {
                    $form->pay_time = date('Y-m-d H:i:s');

                    try {
                        if ($userCoin->transfer_status) {
                            throw new \Exception('无法重复兑付');
                        }

                        if (!$userCoin->user->miniprogram_openid) {
                            throw new \Exception('用户未绑定微信openid');
                        }

                        // 转换金额为分
                        $amount = (int)($userCoin->coin->cost * 100);
//                        if ($amount < 30 || $amount > 200000) {
//                            throw new \Exception('转账金额必须在0.3元到2000元之间');
//                        }

                        // 生成唯一批次号和明细号
                        $outBatchNo = date('YmdHis') . mt_rand(1000, 9999);
                        $outDetailNo = $outBatchNo . mt_rand(1000, 9999);

                        // 商户号
                        $merchantId = config('wechat.mini_program.default.mch_id');

                        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
                        $merchantPrivateKeyFilePath = 'file://' . config('wechat.mini_program.default.key_path');
                        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);

                        // 「商户API证书」的「证书序列号」
                        $merchantCertificateSerial = config('wechat.mini_program.default.certificate_serial');

                        // 从本地文件中加载「微信支付平台证书」或者「微信支付平台公钥」，用来验证微信支付应答的签名
                        $platformCertificateOrPublicKeyFilePath = 'file://' . config('wechat.mini_program.default.platform_certificate');
                        $platformPublicKeyInstance = Rsa::from($platformCertificateOrPublicKeyFilePath, Rsa::KEY_TYPE_PUBLIC);

                        // 「微信支付平台证书」的「证书序列号」或者是「微信支付平台公钥ID」
                        // 「平台证书序列号」及/或「平台公钥ID」可以从 商户平台 -> 账户中心 -> API安全 直接查询到
                        $platformCertificateSerialOrPublicKeyId = config('wechat.mini_program.default.platform_certificate_serial');

                        // 构造一个 APIv3 客户端实例
                        $instance = Builder::factory([
                            'mchid' => $merchantId,
                            'serial' => $merchantCertificateSerial,
                            'privateKey' => $merchantPrivateKeyInstance,
                            'certs' => [
                                $platformCertificateSerialOrPublicKeyId => $platformPublicKeyInstance,
                            ],
                        ]);

                        $resp = $instance->chain('v3/transfer/batches')->post(['json' => [
                            'appid' => config('wechat.mini_program.default.app_id'),
                            'out_batch_no' => $outBatchNo,
                            'batch_name' => date('Y年m月d日') . '用户提现',
                            'batch_remark' => date('Y年m月d日') . '用户提现操作单',
                            'total_amount' => $amount,
                            'total_num' => 1,
                            'transfer_detail_list' => [
                                [
                                    'out_detail_no' => $outDetailNo,
                                    'transfer_amount' => $amount,
                                    'transfer_remark' => '提现到账零钱',
                                    'openid' => $userCoin->user->miniprogram_openid,
                                ]
                            ],
//                            'notify_url' => config('app.url') . '/api/wechat/transfer/notify'
                        ]]);

                        if ($resp->getStatusCode() != 200) {
                            throw new \Exception('转账请求失败: ' . $resp->getBody());
                        }

                        // 解析响应
                        $result = json_decode($resp->getBody(), true);
                        if (!isset($result['batch_id'])) {
                            throw new \Exception('未获取到批次单号');
                        }

                        // 记录转账信息
                        $userCoin->transfer_batch_no = $result['batch_id'];
                        $userCoin->transfer_detail_no = $outDetailNo;
                        $userCoin->transfer_amount = $amount;
                        $userCoin->out_batch_no = $outBatchNo;
                        $userCoin->out_detail_no = $outDetailNo;
                        $userCoin->transfer_status = $result['batch_status'] ?? 'PROCESSING';
                        $userCoin->save();
                    } catch (\Exception $e) {
                        throw new \Exception('转账失败: ' . $e->getMessage());
                    }
                } else {
                    if ($userCoin->transfer_status) {
                        throw new \Exception('已兑付，不支持更改状态');
                    }
                }
            });
        });
    }
}
